package com.xiaoyilin.demo.config.aop;

import com.xiaoyilin.demo.enums.ReturnCode;
import com.xiaoyilin.demo.utils.CommonResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;

/**
 * 统一封装返回值和异常处理
 */
//@Slf4j
//@Aspect
//@Order(5)
//@Component
public class ResponseAop {

    @Pointcut("execution(public * com.xiaoyilin.demo.controller..*(..))")
    public void httpResponse() {
    }

    @Around("httpResponse()")
    public CommonResponse handlerController(ProceedingJoinPoint proceedingJoinPoint) {
        CommonResponse commonResponse = new CommonResponse();
        try {
            //获取方法的执行结果
            Object proceed = proceedingJoinPoint.proceed();
            //如果方法的执行结果是ReturnVO，则将该对象直接返回
            if (proceed instanceof CommonResponse) {
                commonResponse = (CommonResponse) proceed;
            } else {
                //否则，就要封装到ReturnVO的data中
                commonResponse.setData(proceed);
            }
        } catch (Throwable throwable) {
            //如果出现了异常，调用异常处理方法将错误信息封装到ReturnVO中并返回
            commonResponse = handlerException(throwable);
        }
        return commonResponse;
    }

    /**
     * 异常处理
     */
    private CommonResponse handlerException(Throwable throwable) {
        CommonResponse commonResponse = new CommonResponse();
        //这里需要注意，返回枚举类中的枚举在写的时候应该和异常的名称相对应，以便动态的获取异常代码和异常信息
        //获取异常名称的方法
        String errorName = throwable.toString();
        errorName = errorName.substring(errorName.lastIndexOf(".") + 1);
        commonResponse.setMessage(ReturnCode.valueOf(errorName).msg());
        commonResponse.setCode(ReturnCode.valueOf(errorName).val());
        return commonResponse;
    }


}
